package org.msn.client.handler;

import io.netty.channel.ChannelHandlerContext;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.stage.Stage;
import lombok.SneakyThrows;
import org.msn.component.OtherMessageHBox;
import org.msn.config.MessageInfo;
import org.msn.config.RoomInfo;
import org.msn.gui.controller.*;
import org.msn.gui.init.MsnInit;
import org.msn.gui.init.SelfSoundAndVideoInit;
import org.msn.gui.init.ShowAllRoomInit;
import org.msn.rest.RestCode;
import org.msn.rest.RestResult;
import org.msn.util.MapUtil;
import org.msn.util.RequestUtil;

import java.util.List;
import java.util.Map;

public class ClientHandler extends RequestHandler {
    @Override
    protected void sendMsg(ChannelHandlerContext ctx, Object data) {
        // 默认其 data 数据是 messageInfo
        MessageInfo messageInfo = MapUtil.createEntityFromMap((Map<String, Object>) data, MessageInfo.class);

        // 将消息拼接输出到消息面板上
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                MsnInit.exportChatPane.getChildren().add(new OtherMessageHBox(messageInfo.getUsername(), messageInfo.getMsg()));
            }
        });
    }

    @Override
    protected void getAllRoom(ChannelHandlerContext ctx, Object data) {
        List<String> list = (List<String>) data;
        // 如果当前没有房间信息 直接返回
        if (list == null || list.size() == 0) {
            return;
        }

        // 加载有的房间信息到 列表中
        for (String key : list) {
            ShowAllRoomInit.exportRooms.add(key);
        }
    }

    @Override
    protected void successJoinRoom(ChannelHandlerContext ctx, Object data) {
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                MsnInit.exportRoomName.setText(ShowAllRoomInit.exportSelectRoomName);
                MsnController.exportShowAllRoomStage.close();
            }
        });
    }

    @Override
    protected void failJoinRoom(ChannelHandlerContext ctx, Object data) {
        // 房间未加入成功
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                Alert alert2 = new Alert(Alert.AlertType.INFORMATION);
                alert2.setTitle("房间信息");
                alert2.setContentText("人数已满");
                alert2.showAndWait();
            }
        });
    }

    @Override
    protected void getRoomAllUserIP(ChannelHandlerContext ctx, Object data) {
        // 获取所有该房间中用户的 ip 地址
        // 并且给 javacv 使用
        SelfSoundAndVideoInit.userIP = (List<String>) data;
    }

    @Override
    protected void openVideo(ChannelHandlerContext ctx, Object data) {
        sendGetRoomAllUserIP(ctx, RoomInfo.builder().name(MsnInit.exportRoomName.getText()).build());
        // 打开展示自己的视频面板
        openSelfVideo();
        // 同时打开展示其他人的视频面板
        openOtherVideo();
    }

    @Override
    protected void openSound(ChannelHandlerContext ctx, Object data) {
        sendGetRoomAllUserIP(ctx, RoomInfo.builder().name(MsnInit.exportRoomName.getText()).build());
        openSelfSound();
        openOtherSound();
    }

    @Override
    protected void sendCreateRoom(ChannelHandlerContext ctx, Object data) {
        RestResult restResult = new RestResult(RestCode.createRoom, data);
        RequestUtil.sendRequest(ctx, restResult);
    }

    @Override
    protected void sendGetAllRoom(ChannelHandlerContext ctx, Object data) {
        RestResult restResult = new RestResult(RestCode.getAllRoom, data);
        RequestUtil.sendRequest(ctx, restResult);
    }

    @Override
    protected void sendSendMsg(ChannelHandlerContext ctx, Object data) {
        RestResult restResult = new RestResult(RestCode.sendMsg, data);
        RequestUtil.sendRequest(ctx, restResult);
    }

    @Override
    protected void sendLeaveRoom(ChannelHandlerContext ctx, Object data) {
        RestResult restResult = new RestResult(RestCode.leaveRoom, data);
        RequestUtil.sendRequest(ctx, restResult);
    }

    @Override
    protected void sendJoinRoom(ChannelHandlerContext ctx, Object data) {
        RestResult restResult = new RestResult(RestCode.joinRoom, data);
        RequestUtil.sendRequest(ctx, restResult);
    }

    @Override
    protected void sendGetRoomAllUserIP(ChannelHandlerContext ctx, Object data) {
        RestResult restResult = new RestResult(RestCode.getRoomAllUserIP, data);
        RequestUtil.sendRequest(ctx, restResult);
    }

    @Override
    protected void sendOpenVideo(ChannelHandlerContext ctx, Object data) {
        RestResult restResult = new RestResult(RestCode.openVideo, data);
        RequestUtil.sendRequest(ctx, restResult);
    }

    @Override
    protected void sendOpenSound(ChannelHandlerContext ctx, Object data) {
        RestResult restResult = new RestResult(RestCode.openSound, data);
        RequestUtil.sendRequest(ctx, restResult);
    }

    private void openSelfVideo() {
        Platform.runLater(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                Stage stage = new Stage();
                Parent root = FXMLLoader.load(getClass().getResource("/fxml/selfVideoFxml.fxml"));
                stage.setScene(new Scene(root, 100, 100));
                SelfVideoController.stop = true;
                stage.setOnCloseRequest((e) -> {
                    SelfVideoController.stop = false;
                });

                MsnInit.exportSelfVideoStage = stage;

                stage.show();
            }
        });
    }

    private void openOtherVideo() {
        Platform.runLater(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                Stage stage = new Stage();
                Parent root = FXMLLoader.load(getClass().getResource("/fxml/otherVideoFxml.fxml"));
                stage.setScene(new Scene(root, 600, 600));
                OtherVideoController.stop = true;
                stage.setOnCloseRequest((e) -> {
                    OtherVideoController.stop = false;
                });

                MsnInit.exportOtherVideoStage = stage;
                stage.show();
            }
        });
    }

    private void openSelfSound() {
        Platform.runLater(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                Stage stage = new Stage();
                Parent root = FXMLLoader.load(getClass().getResource("/fxml/selfSoundFxml.fxml"));
                stage.setTitle("自己");
                stage.setScene(new Scene(root, 200, 200));
                SelfSoundController.stop = true;
                stage.setOnCloseRequest((e) -> {
                    SelfSoundController.stop = false;
                });

                MsnInit.exportSelfSoundStage = stage;

                stage.show();
            }
        });
    }

    private void openOtherSound() {
        Platform.runLater(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                Stage stage = new Stage();
                Parent root = FXMLLoader.load(getClass().getResource("/fxml/otherSoundFxml.fxml"));
                stage.setTitle("其他人");
                stage.setScene(new Scene(root, 200, 200));
                OtherSoundController.stop = true;
                stage.setOnCloseRequest((e) -> {
                    OtherSoundController.stop = false;
                });

                MsnInit.exportOtherSoundStage = stage;
                stage.show();
            }
        });
    }
}
